package com.wjj.sixinone.service.minio.impl;

import com.wjj.sixinone.common.enums.ExceptionEnum;
import com.wjj.sixinone.common.enums.TPServiceEnum;
import com.wjj.sixinone.common.exception.GlobalException;
import com.wjj.sixinone.common.pojo.log.TPServerLogs;
import com.wjj.sixinone.common.util.AuthContextUtil;
import com.wjj.sixinone.common.util.CurrentIpUtils;
import com.wjj.sixinone.common.util.Result;
import com.wjj.sixinone.common.util.TPServerBeanUtil;
import com.wjj.sixinone.config.MinioConfig;
import com.wjj.sixinone.service.minio.MinioFileService;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.UUID;

@Service
public class MinioFileServiceImpl implements MinioFileService {
    @Autowired
    MinioConfig configuration;
    @Autowired
    MinioClient minioClient;
    @Autowired
    MongoTemplate mongoTemplate;

    /**
     * 上传文件
     *
     * @param file 文件
     * @return 文件名
     */
    public String uploadFile(MultipartFile file) {

        String serverUrl = configuration.getMinioEndpoint();
        // 获取桶名
        String bucketName = configuration.getBucketName();
        //给文件生成一个唯一名称  当日日期-uuid.后缀名
        String folderName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"));
        String fileName = String.valueOf(UUID.randomUUID());
        String originalFilename = file.getOriginalFilename();
        if (originalFilename==null){
            throw new GlobalException(ExceptionEnum.INVALID_FILE_TYPE);
        }
        String extName = originalFilename.substring(file.getOriginalFilename().lastIndexOf("."));//文件后缀名
        String objectName = folderName + "-" + fileName + extName;

        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
            // 配置参数
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(objectName)
                    .stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build();
            //文件名称相同会覆盖
            minioClient.putObject(objectArgs);
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |
                 XmlParserException e) {
            TPServerLogs tpServerLogs = TPServerBeanUtil.buildBean(e);

            mongoTemplate.save(tpServerLogs);
            throw new RuntimeException(e);

        }
        return serverUrl + "/" + bucketName + "/" + objectName;
    }
    public String uploadBase64File(String base64Data) {
        String serverUrl = configuration.getMinioEndpoint();
        // 获取桶名
        String bucketName = configuration.getBucketName();

        if(base64Data.startsWith("data:image/png;base64,")){
            base64Data = base64Data.replace("data:image/png;base64,", "");
        }
        if(base64Data.startsWith("data:image/jpeg;base64,")){
            base64Data = base64Data.replace("data:image/jpeg;base64,", "");
        }
        if(base64Data.startsWith("data:image/jpg;base64,")){
            base64Data = base64Data.replace("data:image/jpg;base64,", "");
        }if(base64Data.startsWith("data:image/webp;base64,")){
            base64Data = base64Data.replace("data:image/webp;base64,", "");
        }
        byte[] data = Base64.getDecoder().decode(base64Data);

        String folderName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"));
        String fileName = String.valueOf(UUID.randomUUID());
        String extName = ".jpg";
        String objectName = folderName + "-" + fileName + extName;

        try {
            ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(objectName)
                    .stream(inputStream, data.length, -1).contentType("image/jpeg").build();
            minioClient.putObject(objectArgs);
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |
                 XmlParserException e) {
            TPServerLogs tpServerLogs = TPServerBeanUtil.buildBean(e);

            mongoTemplate.save(tpServerLogs);
            throw new RuntimeException(e);
        }

        return serverUrl + "/" + bucketName + "/" + objectName;
    }

    public Resource downloadFile(String filePath) {
        // 获取桶名
        String bucketName = configuration.getBucketName();
        try {
            String[] parts = filePath.split("/");
            String fileName = parts[parts.length - 1];
            // 从MinIO下载文件
            InputStream inputStream = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .build());

            // 创建一个临时文件并将文件内容写入
            File tempFile = File.createTempFile("temp-file", null);
            FileOutputStream outputStream = new FileOutputStream(tempFile);
            IOUtils.copy(inputStream, outputStream);
            outputStream.close();

            // 返回文件资源
            return new FileSystemResource(tempFile);
        } catch (Exception e) {
            TPServerLogs tpServerLogs = TPServerBeanUtil.buildBean(e);

            mongoTemplate.save(tpServerLogs);
            throw new RuntimeException("文件下载失败：" + e.getMessage());
        }
    }

    public void deleteFileFromMinio(String url) {
        // 获取桶名
        String bucketName = configuration.getBucketName();
        String objectName = url.substring(url.lastIndexOf("/") + 1);
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (NoSuchAlgorithmException | InvalidKeyException | IOException |
                 MinioException e) {
            TPServerLogs tpServerLogs = TPServerBeanUtil.buildBean(e);
            mongoTemplate.save(tpServerLogs);
            throw new RuntimeException("在minio里面删除失败", e);
        }
    }

}
